//-------------------------------------------------------------------------------------
// <copyright file="ReceivePort.cs" company="Microsoft">
//      Copyright (c) 2003 Microsoft Corporation. All rights reserved.
//      THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
//      EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
//      WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
// </copyright>
// <summary>
//      Represents the logical port through which partners interact with the business process for sending messages.
// </summary>  
//-------------------------------------------------------------------------------------

namespace Microsoft.Sdc.Tasks.BizTalk2004.Configuration
{
	#region Using directives

	using System;
	using System.Collections;
	using System.Reflection;

	#endregion 


	/// <summary>
	/// Represents a business partner or an internal department that the orchestrations interacts with.
	/// </summary>
	internal class Party : BizTalkConfigurableEntityBase
	{
		#region member variables

		private AliasCollection aliases = new AliasCollection();
		private SendPortCollection sendPorts = new SendPortCollection();
		private CertificateInfo signatureCert; 

		#endregion


		#region properties 
		
		/// <summary>
		/// Gets the collection of aliases for the party.
		/// </summary>
		public AliasCollection Aliases
		{
			get {return this.aliases;}
		}

		/// <summary>
		/// Gets the list of send ports that the party references.
		/// </summary>
		public SendPortCollection SendPorts
		{
			get {return this.sendPorts;}
		}

		/// <summary>
		/// Gets or sets the signature certificate used to verify the signature of the documents from this party.
		/// </summary>
		public CertificateInfo SignatureCert
		{
			get {return this.signatureCert;}
			set {this.signatureCert = value;}
		}

		
		#endregion 
		
		
		#region methods 
				
		/// <summary>
		/// Creates a new instance of a party.
		/// </summary>
		/// <param name="installation"> The <see cref="Microsoft.Sdc.Tasks.BizTalk2004.Configuration.BizTalkInstallation"/> object of this party.</param>
		/// <param name="name">The name of this party.</param>
		public Party(BizTalkInstallation installation, string name): base(installation, name)
		{

		}


		/// <summary>
		/// Creates a new instance of a party. This method is private and is called by the Load method.
		/// </summary>
		/// <param name="installation"> The <see cref="Microsoft.Sdc.Tasks.BizTalk2004.Configuration.BizTalkInstallation"/> object of this party.</param>
		private Party(BizTalkInstallation installation):base(installation)
		{
			this.Loaded = true;
		}

		
		/// <summary>
		/// 
		/// </summary>
		/// <param name="installation"></param>
		/// <param name="name"></param>
		/// <returns></returns>
		public static Party Load(BizTalkInstallation installation, string name)
		{
			//loading native type
			BtsParty actualParty = installation.CatalogExplorer.Parties[name];
			
			Party party = null;

			if (actualParty != null)
			{
				party = new Party(installation);
				party.Name = actualParty.Name;
				
				//signaturecert
				if (actualParty.SignatureCert != null)
					party.signatureCert = installation.Certificates[actualParty.SignatureCert.LongName];

				//sendports
				if (actualParty.SendPorts.Count > 0)
					foreach(object port in actualParty.SendPorts)
					{
						BtsSendPort sendport = new BtsSendPort(port, actualParty.BtsCatalogExplorer);
						party.sendPorts.Add(SendPort.Load(installation, sendport.Name));
					}

				//aliases
				if (actualParty.Aliases.Count > 0)
					foreach(BtsPartyAlias actualAlias in actualParty.Aliases)
						party.aliases.Add(Alias.Load(party, actualAlias.Qualifier, actualAlias.Value));

			}

			return party;
		}

		
		/// <summary>
		/// Saves the party object
		/// </summary>
		protected internal override void SaveImpl()
		{
			BtsParty actualParty = null;

			//loading / creating the party
			if (this.Loaded)
				actualParty = this.Installation.CatalogExplorer.Parties[this.Name];
			else
				actualParty = this.Installation.CatalogExplorer.AddNewParty();

			//name
			actualParty.Name = this.Name;

			//signaturecert
			if (this.signatureCert != null)
			{
				foreach(BtsCertificateInfo certInfo in this.Installation.CatalogExplorer.Certificates)
				{
					if (certInfo.LongName == this.signatureCert.LongName)
					{
						actualParty.SignatureCert = certInfo;
						break;
					}
				}
			}

			//sendports
			if (this.sendPorts.Count > 0)
			{
				actualParty.SendPorts.Clear();
				foreach(SendPort port in this.sendPorts)
					actualParty.SendPorts.Add(this.Installation.CatalogExplorer.SendPorts[port.Name].actualBtsObject);
			}
		}
		
		/// <summary>
		/// Checks if the Receive Port exists within BizTalk
		/// </summary>
		/// <param name="installation">
		/// The BizTalk.Installation to search in.
		/// </param>
		/// <param name="name">
		/// The name of the Party
		/// </param>
		/// <returns>
		/// <b>true</b> if the Party exists, <b>false</b> otherwise.
		/// </returns>
		public static bool Exists(BizTalkInstallation installation, string name)
		{
			return BizTalkEntityBase.Exists(installation, CollectionType.Party, name);
		}		

		/// <summary>
		/// Deletes a party.
		/// </summary>
		/// <param name="installation">
		/// The Microsoft.Sdc.Tasks.Configuration.BizTalk.Installation to delete the party from.
		/// </param>
		/// <param name="name">The name of the party to delete.</param>
        public static void Delete(BizTalkInstallation installation, string name)
        {
            BtsParty actualParty = installation.CatalogExplorer.Parties[name];

            if (actualParty != null)
            {
                installation.CatalogExplorer.RemoveParty(actualParty);
                installation.CatalogExplorer.SaveChanges();
            }
            else
                throw new InvalidOperationException("Party does not exist.");
        }

		/// <summary>
		/// Deletes the current party.
		/// </summary>
		public void Delete()
		{
			Party.Delete(this.Installation, this.Name);
		}

		/// <summary>
		/// Creates and adds a new alias to the party.
		/// </summary>
		/// <param name="name">The name of the alias.</param>
		/// <param name="qualifier">The qualifier of the alias.</param>
		/// <param name="value">The value of the alias.</param>
		public void AddNewAlias(string name, string qualifier, string value)
		{
			BtsParty actualParty = this.Installation.CatalogExplorer.Parties[this.Name];
			
			BtsPartyAlias actualAlias = actualParty.AddNewAlias();
			actualAlias.Name = name;
			actualAlias.Qualifier = qualifier;
			actualAlias.Value = value;

			this.Installation.CatalogExplorer.SaveChanges();
		}
		
		/// <summary>
		/// Updates the alias of a Party
		/// </summary>
		/// <param name="oldName"></param>
		/// <param name="oldQualifier"></param>
		/// <param name="oldValue"></param>
		/// <param name="newName"></param>
		/// <param name="newQualifier"></param>
		/// <param name="newValue"></param>
		public void UpdateAlias(string oldName, string oldQualifier, string oldValue, string newName, string newQualifier, string newValue)
		{
			BtsPartyAlias actualAlias = null;
			
			foreach(Alias alias in this.Aliases)
			{
				if (alias.Name == oldName && alias.Qualifier == oldQualifier && alias.Value == oldValue)
				{
					actualAlias = this.Installation.CatalogExplorer.Parties[this.Name].Aliases[alias.Qualifier, alias.Value];
					break;
				}
			}

			if (actualAlias != null)
			{
				//setting up new values
				actualAlias.Name = (newName != null || newName != string.Empty)?newName:actualAlias.Name;
				actualAlias.Qualifier = (newQualifier != null || newQualifier != string.Empty)? newQualifier:actualAlias.Qualifier;
				actualAlias.Value = (newValue != null || newValue != string.Empty)?newValue:actualAlias.Value;

				this.Installation.CatalogExplorer.SaveChanges();
			}
			else
				throw new InvalidOperationException("Alias does not exist.");
		}
		
		/// <summary>
		/// Deletes an existing alias of the party
		/// </summary>
		/// <param name="qualifier">The qualifier of the alias.</param>
		/// <param name="value">The value of the alias.</param>
		public void DeleteAlias(string qualifier, string value)
		{
			foreach(Alias alias in this.Aliases)
			{
				if (alias.Qualifier == qualifier && alias.Value == value)
				{
					BtsParty actualParty = this.Installation.CatalogExplorer.Parties[this.Name];
					BtsPartyAlias actualAlias = actualParty.Aliases[qualifier, value];

					actualParty.RemoveAlias(actualAlias);

					this.Installation.CatalogExplorer.SaveChanges();
				}
			}
		}
		#endregion 
	}
}

